﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Lights.Types
{
    /// <summary>
    /// Rappresenta una foto nell'archivio
    /// </summary>
    [Serializable]
    public class Photo
    {
        #region Properties
        /// <summary>
        /// Ottiene l'immagine originale
        /// </summary>
        public BitmapSource OriginalImage 
        {
            get
            {
                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                bmp.CreateOptions = BitmapCreateOptions.DelayCreation;
                bmp.CacheOption = BitmapCacheOption.None;
                bmp.StreamSource = File.OpenRead(Global.CatalogFolder + "/" + hashcode.ToString());
                bmp.EndInit();
                bmp.Freeze();

                BitmapSource img = bmp;
                if (img.Format != PixelFormats.Bgra32)
                    img = new FormatConvertedBitmap(img, PixelFormats.Bgra32, null, 0);

                return img;
            } 
        }
        public BitmapSource Preview
        {
            get
            {
                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                bmp.CreateOptions = BitmapCreateOptions.DelayCreation;
                bmp.CacheOption = BitmapCacheOption.None;
                //bmp.DecodePixelWidth = Global.PREVIEW_SIZE;
                bmp.StreamSource = File.OpenRead(Global.CatalogFolder + "/" + hashcode.ToString());
                bmp.EndInit();
                bmp.Freeze();

                BitmapSource img = bmp;
                if (img.Format != PixelFormats.Bgra32)
                    img = new FormatConvertedBitmap(img, PixelFormats.Bgra32, null, 0);

                return img;
            }
        }
        /// <summary>
        ///  Ottiene l'immagine di anteprima della foto
        /// </summary>
        public BitmapSource Thumbnail 
        {
            get
            {
                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                bmp.CreateOptions = BitmapCreateOptions.DelayCreation;
                bmp.CacheOption = BitmapCacheOption.OnLoad;
                bmp.DecodePixelWidth = Global.THUMBNAIL_SIZE;
                bmp.StreamSource = File.OpenRead(Global.CatalogFolder + "/" + hashcode.ToString());
                bmp.EndInit();
                bmp.Freeze();
                return bmp;
           } 
        }
        
        /// <summary>
        /// Ottiene un codice univoco per questa istanza.
        /// </summary>
        public int Hashcode { get { return this.hashcode; } }

        /// <summary>
        ///  Restituisce il nome della funzione.
        /// </summary>
        public string Name { get { return this.name; } }

        public bool IsSelected { get; set; }

        public DateTime Imported { get; private set; }

        #endregion

        #region Fields
        public Dictionary<string, object[]> Filters;
        string name;
        int hashcode;
        #endregion

        #region Methods
        public static Photo Import(string src)
        {
            // apro l'immagine originale
            byte[] buffer = File.ReadAllBytes(src);

            // calcolo l'hashcode
            int hashcode = 0;
            byte[] hashBuffer = MD5.Create().ComputeHash(buffer);
            for (int i = 0; i < hashBuffer.Length; i += 4)
            {
                hashcode ^= (hashBuffer[i] | hashBuffer[i + 1] << 8 | hashBuffer[i + 2] << 16 | hashBuffer[i + 3] << 24);
            }
            
            // salvo l'immagine nel catalogo
            File.WriteAllBytes(Global.CatalogFolder + "/" + hashcode.ToString(), buffer);

            Photo photo = new Photo(Path.GetFileNameWithoutExtension(src), hashcode);
            photo.Imported = DateTime.Now;

            // restituisco l'istanza della foto importata
            return photo;
        }

        private Photo(string name, int hashcode)
        {
            this.name = name;
            this.hashcode = hashcode;
            this.Filters = new Dictionary<string, object[]>();
        }

        /// <summary>
        /// Restituisce l'id univoco di questo oggetto.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.hashcode;
        }
        /// <summary>
        /// Restituisce una rappresentazione letterale dell'oggetto.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.name;
        }
        #endregion
    }
}
